﻿using ArtMath.Animation;
using ArtMath.Component.Point;
using System;
using System.Collections.Generic;
using ArtMath.Command;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using ArtMath.Resource;
using ArtMath.Setting;
using ArtMath.Core.Helper;
using ArtMath.Flag;
using System.ComponentModel;
using System.Linq;
using ArtMath.CommonType;

namespace ArtMath.Window
{
    public partial class AnimationsManagerWindow : DockContent
    {
        [Browsable(false)]
        public SketchPad LinkedPad { get; private set; }
        public event Action<bool> AnimationStateChanged;
        public void SketchPad_Activated(SketchPad pad)
        {
            lvAnimation.Items.Clear();
            LinkedPad = pad;
            if (LinkedPad == null)
            {
                //lvAnimation.Enabled = toolStrip4.Enabled = false;
                Enabled = false;
                Text = Resources.JoinLocalizedString("Animation", "Manager");
            }
            else
            {
                foreach (AnimationBase item in LinkedPad.Animations)
                {
                    lvAnimation.Items.Add(item.AnimationsManagerItem);
                }
                //lvAnimation.Enabled = toolStrip4.Enabled = true;
                Enabled = true;
            }
        }
        public AnimationsManagerWindow()
        {
            InitializeComponent();
            splitContainer1.Panel2Collapsed = true;
            ChangeColorTheme(Settings.Instance.ColorTheme);
        }
        public void ChangeColorTheme(UIColorTheme theme)
        {
            switch (theme)
            {
                case UIColorTheme.Light:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015LightTheme1);
                    break;
                case UIColorTheme.Blue:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015BlueTheme1);
                    break;
                case UIColorTheme.Dark:
                    EnableVSRenderer(VisualStudioToolStripExtender.VsVersion.Vs2015, vS2015DarkTheme1);
                    break;
            }
        }
        void EnableVSRenderer(VisualStudioToolStripExtender.VsVersion version, ThemeBase theme)
        {
            visualStudioToolStripExtender1.SetStyle(toolStrip4, version, theme);
            visualStudioToolStripExtender1.SetStyle(cmsItem, version, theme);
            visualStudioToolStripExtender1.SetStyle(cmsList, version, theme);
        }
        //public ListView AnimationList
        //{
        //    get { return lvAnimation; }
        //}
        private void lvAnimation_EnabledChanged(object sender, EventArgs e)
        {
            toolStrip4.Enabled = lvAnimation.Enabled;
        }

        private void tsbAddAction_Click(object sender, EventArgs e)
        {
            AddAnimation();
        }
        public void AddAnimation()
        {
            AddAnimationWindow aa = new AddAnimationWindow(LinkedPad);
            if (aa.ShowDialog() == DialogResult.OK)
            {
                aa.ForEachSelectedPoint((PointBase pt) =>
                {
                    AnimationBase ani;
                    if (aa.UseHighPerformanceAnimation)
                    {
                        ani = new HighPerformanceAnimation(pt, aa.LineSpeed, aa.Rate, aa.AnimationDirection);
                    }
                    else
                    {
                        ani = new NormalAnimation(pt, aa.LineSpeed, aa.Rate, aa.AnimationDirection);
                    }
                    LinkedPad.Animations.Add(ani);
                    LinkedPad.AddNewCommand(new AddObject<AnimationBase>(ani), false);
                    AnimationCreated(LinkedPad, ani);
                    LinkedPad.Document.Modified = true;
                    return true;
                });
            }
        }
        public void AnimationCreated(SketchPad sender, AnimationBase ani)
        {
            ani.RegisterAnimationEvents();
            lvAnimation.Items.Add(ani.AnimationsManagerItem);
        }
        private void lvAnimation_SelectedIndexChanged(object sender, EventArgs e)
        {
            tsbDeleteAction.Enabled = tsbReverse.Enabled = tsbResetTime.Enabled = lvAnimation.SelectedItems.Count > 0;
            if (lvAnimation.SelectedItems.Count > 0)
            {
                LinkedPad.Layer.SelectNone();
                Text = $"{Resources.JoinLocalizedString("Animation", "Manager")} - " + (lvAnimation.SelectedItems.Count == 1 ? lvAnimation.SelectedItems[0].SubItems[0].Text : $"({Resources.JoinLocalizedString("Multiple", "Animation")})");
                object[] anis = new object[lvAnimation.SelectedItems.Count];
                bool enableRun = false, enableStop = false;
                for (int i = 0; i < anis.Length; i++)
                {
                    AnimationBase ani = lvAnimation.SelectedItems[i].Tag as AnimationBase;
                    anis[i] = ani;
                    if (ani.IsRunning)
                    {
                        enableStop = true;
                    }
                    else
                    {
                        enableRun = true;
                    }
                }
                tsbRun.Enabled = enableRun;
                tsbStop.Enabled = enableStop;
                Program.WinProperty.PropertyGrid.SelectedObjects = anis;
                Program.WinProperty.Text = $"{Resources.Translate("Property")} - " + (lvAnimation.SelectedItems.Count == 1 ? lvAnimation.SelectedItems[0].SubItems[0].Text : $"({Resources.JoinLocalizedString("Multiple", "Animation")})");
                lvAnimation.ContextMenuStrip = cmsItem;
            }
            else
            {
                tsbRun.Enabled = tsbStop.Enabled = false;
                Text = Resources.JoinLocalizedString("Animation", "Manager");
                lvAnimation.ContextMenuStrip = cmsList;
                if (Program.WinProperty.PropertyGrid.SelectedObjects != null &&
                    Program.WinProperty.PropertyGrid.SelectedObjects.All((object obj) =>
                {
                    return obj is AnimationBase;
                }))
                {
                    Program.WinProperty.PropertyGrid.SelectedObjects = null;
                    Program.WinProperty.Text = Resources.Translate("Property");
                }
            }
        }

        private void tsbRun_Click(object sender, EventArgs e)
        {
            ChangeRunningState(true);
        }
        public void ChangeRunningState(bool run, bool all = false)
        {
            foreach (ListViewItem item in lvAnimation.GetItems(all))
            {
                AnimationBase action = item.Tag as AnimationBase;
                if (run)
                {
                    if (!action.IsRunning)
                    {
                        action.Run();
                    }
                }
                else
                {
                    if (action.IsRunning)
                    {
                        action.Stop();
                    }
                }
            }
            lvAnimation_SelectedIndexChanged(lvAnimation, EventArgs.Empty);
            bool containsRunning = run;
            if (!run)
            {
                foreach (ListViewItem item in lvAnimation.Items)
                {
                    AnimationBase action = item.Tag as AnimationBase;
                    if (action.IsRunning)
                    {
                        containsRunning = true;
                        break;
                    }
                }
            }
            AnimationStateChanged?.Invoke(containsRunning);
            LinkedPad.Document.Modified = true;
        }
        private void tsbStop_Click(object sender, EventArgs e)
        {
            ChangeRunningState(false);
        }

        private void tsbReverse_Click(object sender, EventArgs e)
        {
            Reverse();
        }
        public void Reverse(bool all = false)
        {
            foreach (ListViewItem item in lvAnimation.GetItems(all))
            {
                AnimationBase action = item.Tag as AnimationBase;
                action.Reverse();
            }
            LinkedPad.Document.Modified = true;
        }
        private void tsbDeleteAction_Click(object sender, EventArgs e)
        {
            DeleteAnimations();
        }
        public void DeleteAnimations(bool all = false)
        {
            bool sft = Flags.Shift;
            if (sft)
            {
                if (MessageBox.Show(string.Format(Resources.Translate("DeleteObjectAsk"), Resources.Translate("Animation")), Resources.Translate("Ask"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                {
                    return;
                }
            }
            List<AnimationBase> ls = new List<AnimationBase>();
            foreach (ListViewItem item in lvAnimation.GetItems(all))
            {
                AnimationBase action = item.Tag as AnimationBase;
                if (action.IsRunning)
                {
                    DialogResult dr = MessageBox.Show(string.Format(Resources.Translate("AnimationRunning"), action.MotionPoint.Name), Resources.Translate("Ask"), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                    if (dr == DialogResult.No)
                    {
                        continue;
                    }
                    else if (dr == DialogResult.Cancel)
                    {
                        return;
                    }
                }
                ls.Add(action);
            }
            if (ls.Count == 0) return;
            if (sft)
            {
                foreach (AnimationBase item in ls)
                {
                    item.Delete();
                }
            }
            else
            {
                DeleteObjects<AnimationBase> del = new DeleteObjects<AnimationBase>(ls);
                try
                {
                    del.Redo();
                }
                catch (Exception ex)
                {
                    HashSet<IRecoverableDelete> done = ex.Data["DeletedObjects"] as HashSet<IRecoverableDelete>;
                    del.RemoveObjects((AnimationBase obj) => { return !done.Contains(obj); });
                    if (ex.Message != Flags.ExceptionShieldMessage)
                    {
                        MessageBox.Show(ex.Message, Resources.Translate("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                finally
                {
                    if (del.ObjectCount > 0)
                    {
                        LinkedPad.AddNewCommand(del, false);
                    }
                }
            }
            if (lvAnimation.Items.Count > 0)
            {
                lvAnimation.Items[0].Selected = true;
            }
            LinkedPad.Document.Modified = true;
        }
        private void tsbResetTime_Click(object sender, EventArgs e)
        {
            ResetDuration();
        }
        public void ResetDuration(bool all = false)
        {
            foreach (ListViewItem item in lvAnimation.GetItems(all))
            {
                AnimationBase action = item.Tag as AnimationBase;
                action.Duration = 0;
            }
            LinkedPad.Document.Modified = true;
        }
        private void 添加动画NToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddAnimation();
        }

        private void 删除DToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DeleteAnimations();
        }

        private void 全部运行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeRunningState(true, true);
        }

        private void 全部停止SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeRunningState(false, true);
        }

        private void 全部转向ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Reverse(true);
        }

        private void 转向ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Reverse();
        }

        private void 重置持续时间ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ResetDuration();
        }

        private void 停止SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeRunningState(false);
        }

        private void 运动RToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeRunningState(true);
        }

        private void tsbDeleteAction_EnabledChanged(object sender, EventArgs e)
        {
            Program.WinMain.NotifyMenuPropertyChanged("删除动画DToolStripMenuItem", nameof(ToolStripItem.Enabled), tsbDeleteAction.Enabled);
        }

        private void tsbRun_EnabledChanged(object sender, EventArgs e)
        {
            Program.WinMain.NotifyMenuPropertyChanged("运动RToolStripMenuItem", nameof(ToolStripItem.Enabled), tsbRun.Enabled);
            运动RToolStripMenuItem.Enabled = tsbRun.Enabled;
        }

        private void tsbStop_EnabledChanged(object sender, EventArgs e)
        {
            Program.WinMain.NotifyMenuPropertyChanged("停止SToolStripMenuItem", nameof(ToolStripItem.Enabled), tsbStop.Enabled);
            停止SToolStripMenuItem.Enabled = tsbStop.Enabled;
        }

        private void tsbReverse_EnabledChanged(object sender, EventArgs e)
        {
            Program.WinMain.NotifyMenuPropertyChanged("转向ToolStripMenuItem", nameof(ToolStripItem.Enabled), tsbReverse.Enabled);
        }

        private void tsbResetTime_EnabledChanged(object sender, EventArgs e)
        {
            Program.WinMain.NotifyMenuPropertyChanged("重置持续时间ToolStripMenuItem", nameof(ToolStripItem.Enabled), tsbResetTime.Enabled);
        }

        private void AnimationsManagerWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                DockState = DockState.Hidden;
                e.Cancel = true;
            }
            Program.WinMain.AnimationManagerMenu.Checked = false;
        }
        public void Animation_Recovered(AnimationBase sender)
        {
            if (sender.Pad.IsSelectedPad)
            {
                lvAnimation.Items.Add(sender.AnimationsManagerItem);
            }
        }
    }
}
